﻿using Awsc.DataAcquisitionSys.Core.DataAcquisition;
using Awsc.DataAcquisitionSys.Core.Model.Config;
using Awsc.DataAcquisitionSys.Core.Models.ServiceModels;
using Awsc.DataAcquisitionSys.Core.Service.DataAcquisition.DataCollectors;
using Awsc.DataAcquisitionSys.Core.Services.ConfigManagement;
using Awsc.DataAcquisitionSys.Core.Services.DataAcquisition.DataCollectors;
using Microsoft.Extensions.DependencyInjection;
using System.Timers;

namespace Awsc.DataAcquisitionSys.Core.Services.DataAcquisition
{
    public class DataCollectEngine
    {
        private System.Timers.Timer timer;
        private Dictionary<string, IDataCollector> dataCollectors = new Dictionary<string, IDataCollector>();
        private readonly IDeviceConfigService deviceConfigService;
        private readonly IServiceProvider serviceProvider;

        public event EventHandler<GlobalDeviceManager> DataRecieved;


        public bool IsRunning { get; set; }


        public DataCollectEngine(IServiceProvider serviceProvider)
        {
            timer = new System.Timers.Timer();
            timer.Interval = 200;
            timer.Elapsed += Timer_Elapsed;
            this.deviceConfigService = serviceProvider.GetRequiredService<IDeviceConfigService>();
            this.serviceProvider = serviceProvider;
        }

        public async Task StartAsync()
        {
            if(IsRunning)
            {
                return;
            }
            var deviceConfig = deviceConfigService.GetDeviceConfig();
            foreach (var collectorConfig in deviceConfig.Collectors)
            {
                var dataCollectionContext = new DataCollectionContext() { Services = serviceProvider, CollectorConfig = collectorConfig };
                var collector = CreateDataCollector(dataCollectionContext);
                if (collector != null)
                {
                    await collector.StartDataCollectionAsync();
                }
            }
            IsRunning = true;
            timer.Start();

        }

        public async Task StopAsync()
        {
            if (IsRunning)
            {
                foreach (var item in dataCollectors.Values)
                {
                    await item.StopDataCollectionAsync();
                }
                IsRunning = false;
                timer.Stop();
            }

        }

        public async Task RestartAsync()
        {

            await StopAsync();

            await StartAsync();
        }

        private IDataCollector CreateDataCollector(DataCollectionContext dataCollectionContext)
        {
            if (dataCollectors.ContainsKey(dataCollectionContext.CollectorConfig.Model))
            {
                return dataCollectors[dataCollectionContext.CollectorConfig.Model];
            }
            IDataCollector dataCollector = null;
            switch (dataCollectionContext.CollectorConfig.Model)
            {
                case "零点系列(1234顺序)":
                case "MT1333":
                case "MT31":
                case "MT30":
                    dataCollector = new AIOBOXCollector(dataCollectionContext);
                    break;
                case "卡特PL1000E":
                case "PL1000E":
                    return new PL1000ECollector(dataCollectionContext);
                case "虚拟采集器":
                case "AbstractCollector":
                    return new AbstractCollector(dataCollectionContext);
                case "无线采集器AWSC1000A":
                case "Awsc1000A":
                    return new Awsc1000ACollector(dataCollectionContext);
                case "J1939协议":
                case "J1939":
                    return new J1939Collector(dataCollectionContext);
                case "卡瓦联动PlcS7200":
                    return new PlcS7200Collector(dataCollectionContext);
                case "液压钳采集器":
                    return new HydraulicTongsCollector(dataCollectionContext);
                case "无线压力采集器":
                    return new WirelessPressureCollector(dataCollectionContext);
            }
            if (dataCollector != null)
            {
                dataCollectors[dataCollectionContext.CollectorConfig.Name] = dataCollector;
            }
            return dataCollector;
        }

        private void Timer_Elapsed(object? sender, ElapsedEventArgs e)
        {
            if (dataCollectors.Values.Any(c => c.Status == DevStatus.S_OK))
            {
                DataRecieved?.Invoke(this, GlobalDeviceManager.Instance);
            }

        }
    }
}
